<?php

/**
 * Provides basic database connection support like running query and collecting
 * messages.
 * @author eX0du5
 *
 */
class DBHandler {

	protected $dbcon               = null;
	private   $show_original_query = true;
	private   $mysql_error         = null;
	private   $mysql_error_no      = null;
	private   $affected_rows       = null;

	/**
	 * Constructor
	 * @param Resource $dbcon MySQL DB connection
	 */
	public function __construct($dbcon) {
		if ($dbcon == null) throw new InvalidArgumentException('DB Connection is null');
		$this->dbcon = $dbcon;
	}

	/**
	 * Execute a query at MySQL and add errors to mysql_error object.
	 *
	 * @param String $query Query to be executed.
	 * @return boolean|resource MySQLResult or false
	 */
	protected function run_mysql_query($query) {
		$this->affected_rows = null; // reset value

		$res = mysql_query($query,$this->dbcon);
		if (!$res) {
			$this->mysql_error = new ErrorObject(ErrorObject::severity_error, mysql_error($this->dbcon));
			if ($this->show_original_query) {
				$this->mysql_error->add_child_message(new ErrorObject(ErrorObject::severity_info , $query));
			}
			$this->mysql_error_no = mysql_errno($this->dbcon);
			return false;
		} else {
			$this->affected_rows = mysql_affected_rows($this->dbcon);
			return $res;
		}
	}

	/**
	 * Returns the number of affected rows from the previous mysql query.
	 * @return null or INT
	 */
	protected function get_affected_rows() {
		return $this->affected_rows;
	}

	/**
	 * Get collected MySQL errors or return null.
	 * @return ErrorObject Error object instance or null
	 */
	protected function get_mysql_error_object() {
		return $this->mysql_error;
	}

	/**
	 * Get last MySQL error number.
	 * @return Ambiguous
	 */
	protected function get_mysql_error_number() {
		return $this->mysql_error_no;
	}

	/**
	 * Delete all MySQL errors to avoid them as child messages in error objects.
	 * This includes the ErrorObject and the Error Number.
	 */
	protected function reset_mysql_error() {
		$this->mysql_error    = null;
		$this->mysql_error_no = null;
	}

	/**
	 * Call this method if the orignal query that caused a mysql error shall not be added
	 * to the ErrorObject instance.
	 */
	protected function suppress_orignal_query_info() {
		$this->show_original_query = false;
	}

	/**
	 * Call this method if the orignal query that caused a mysql error shall be added
	 * to the ErrorObject instance.
	 */
	protected function show_orignal_query_info() {
		$this->show_original_query = true;
	}
}

/**
 * Provides generic methods needed by several sub classes like error handling and DB access
 * @author eX0du5
 *
 */
class GenericSuperclass extends DBHandler {
	/**
	 * Collect all class based messages
	 * @var ErrorObject
	 */
	protected $error_object = null;

	/**
	 * Constructor
	 * @param Resource $dbcon MySQL DB connection
	 */
	public function __construct($dbcon) {
		parent::__construct($dbcon);
	}


	/**
	 * This method will return the collected error messages of a class.
	 * This can be either the class error messages or MySQL error messages.
	 * In case both messages exist, the MySQL messages are added as sub messages
	 * to the class messages.
	 * @return ErrorObject Error object instance or null
	 */
	public function get_error_object() {
		$mysql_error = $this->get_mysql_error_object();
		if ($mysql_error != null) {
			if ($this->error_object == null) {
				$this->error_object = $mysql_error;
			} else {
				$this->error_object->add_child_message($mysql_error);
			}
		}
		return $this->error_object;
	}
}
